﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace PapnKukn.Silverlight.SilverKnight
{
    public partial class Board : UserControl
    {
        #region Declarations
        private Field last = null;
        private int score = 0;
        #endregion

        #region Properties
        public int Score
        {
            get
            {
                return this.score;
            }
            set
            {
                this.score = value;
            }
        }
        #endregion

        #region Constructor
        public Board()
        {
            InitializeComponent();
            loadBoard();
        }
        #endregion

        #region Methods
        public void Reload()
        {
            last = null;
            loadBoard();
        }

        private void loadBoard()
        {
            //Reset score
            this.score = 0;

            //Clear previous graphics
            pnlLayout.Children.Clear();

            //Predict total width and height
            this.Width = AppConfig.DefaultColumnsCount * 20 - AppConfig.DefaultColumnsCount;
            this.Height = AppConfig.DefaultRowsCount * 20 - AppConfig.DefaultRowsCount;

            //Create chessboard
            for (int r = 0; r < AppConfig.DefaultRowsCount; r++)
            {
                for (int c = 0; c < AppConfig.DefaultColumnsCount; c++)
                {
                    Field field = new Field(r, c);
                    double left = (c == 0 ? 0 : c * field.Width - c);
                    double top = (r == 0 ? 0 : r * field.Height - r);
                    field.Margin = new Thickness(left, top, 0, 0);
                    field.Selected += new RoutedEventHandler(field_Selected);
                    field.MouseOver += new RoutedEventHandler(field_MouseOver);

                    //Workaround for Silverlight 2.0 release (it works normally in beta2 if event is attached inside control)
                    field.MouseEnter += new MouseEventHandler(field_MouseEnter);
                    field.MouseLeave += new MouseEventHandler(field_MouseLeave);
                    field.MouseLeftButtonDown += new MouseButtonEventHandler(field_MouseLeftButtonDown);
                    field.Cursor = Cursors.Hand;

                    pnlLayout.Children.Add(field);
                }
            }
        }

        private bool check(int row, int column)
        {
            bool result = false;
            if (row >= 0 && row < AppConfig.DefaultRowsCount && column >= 0 && column < AppConfig.DefaultColumnsCount)
            {
                int index = row * AppConfig.DefaultColumnsCount + column;
                if (index >= 0 && index < pnlLayout.Children.Count)
                {
                    Field field = pnlLayout.Children[index] as Field;
                    result = !field.IsSelected;
                }
            }
            return result;
        }
        #endregion

        #region Events
        protected void field_MouseOver(object sender, RoutedEventArgs e)
        {
            if (sender != null && sender is Field)
            {
                Field field = sender as Field;
                if (last == null)
                {
                    //First selected
                    field.IsAllowed = true;
                }
                else
                {
                    //Chess knight rules
                    if ((field.Row == last.Row - 1 && field.Column == last.Column - 2) ||
                        (field.Row == last.Row + 1 && field.Column == last.Column - 2) ||
                        (field.Row == last.Row - 1 && field.Column == last.Column + 2) ||
                        (field.Row == last.Row + 1 && field.Column == last.Column + 2) ||
                        (field.Row == last.Row - 2 && field.Column == last.Column - 1) ||
                        (field.Row == last.Row + 2 && field.Column == last.Column - 1) ||
                        (field.Row == last.Row - 2 && field.Column == last.Column + 1) ||
                        (field.Row == last.Row + 2 && field.Column == last.Column + 1))
                    {
                        field.IsAllowed = true;
                    }
                    else
                    {
                        field.IsAllowed = false;
                    }
                }
            }
        }

        protected void field_Selected(object sender, RoutedEventArgs e)
        {
            if (sender != null && sender is Field)
            {
                Field field = sender as Field;
                if (field.IsAllowed)
                {
                    this.score++;
                    field.Score = this.score;
                    if (last != null) last.SetColor("BlueBrush");
                    last = field;
                    
                    //field.SetColor("VioletBrush");

                    //Check if any field is allowed to select
                    if (check(last.Row - 1, last.Column - 2) ||
                        check(last.Row + 1, last.Column - 2) ||
                        check(last.Row - 1, last.Column + 2) ||
                        check(last.Row + 1, last.Column + 2) ||
                        check(last.Row - 2, last.Column - 1) ||
                        check(last.Row + 2, last.Column - 1) ||
                        check(last.Row - 2, last.Column + 1) ||
                        check(last.Row + 2, last.Column + 1))
                    {
                        //Play on...
                    }
                    else
                    {
                        OnGameOver(new RoutedEventArgs());
                    }
                }
            }
        }

        private void field_MouseEnter(object sender, MouseEventArgs e)
        {
            if (sender != null && sender is Field)
            {
                Field field = sender as Field;
                field.TriggerMouseEnter(sender, e);
            }
        }

        private void field_MouseLeave(object sender, MouseEventArgs e)
        {
            if (sender != null && sender is Field)
            {
                Field field = sender as Field;
                field.TriggerMouseLeave(sender, e);
            }
        }

        private void field_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (sender != null && sender is Field)
            {
                Field field = sender as Field;
                field.TriggerMouseLeftButtonDown(sender, e);
            }
        }
        #endregion

        #region Bubble events
        public event RoutedEventHandler GameOver;
        protected virtual void OnGameOver(RoutedEventArgs e)
        {
            if (GameOver != null)
            {
                GameOver(this, e);
            }
        }
        #endregion
    }
}
